package dxn.nl.export.deal.netty;

import com.alibaba.excel.util.StringUtils;
import dxn.nl.file.client.model.dto.TransferMessageDto;
import dxn.nl.file.client.model.enums.ExportDealResultTypeEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

public class SocketManager {
    private static final Logger log = LoggerFactory.getLogger(SocketManager.class);
    public static final String appSessionId = UUID.randomUUID().toString().replace("-","");
    public static List<ExportDealServer> dealServerHashMap = new ArrayList<>();
    private static int serverIndex = 0;
    private static final ConcurrentHashMap<String, CompletableFuture<TransferMessageDto>> messageFutureMap = new ConcurrentHashMap<>();

    public static boolean noCentRegister()
    {
        return CollectionUtils.isEmpty(dealServerHashMap);
    }
    private static ExportDealServer getDealServer()
    {
        if(CollectionUtils.isEmpty(dealServerHashMap))
        {
            return null;
        }

        int nextIndex = serverIndex % dealServerHashMap.size();
        serverIndex++;
        if(serverIndex > 124)
        {
            serverIndex = 0;
        }
        return dealServerHashMap.get(nextIndex);
    }

    private static TransferMessageDto sendDataToServer(TransferMessageDto po) {
        TransferMessageDto resultPo = po.convertNewResultMessage();
        try {
            ExportDealServer dealServer = getDealServer();

            if (dealServer == null) {
                resultPo.getConfig().setDealResult(ExportDealResultTypeEnum.fail.code);
                resultPo.getConfig().setErrorMessage("未找到注册中心链接信息");
                return resultPo;
            }

            CompletableFuture<TransferMessageDto> completeFuture = new CompletableFuture<>();
            messageFutureMap.put(po.getConfig().getId(), completeFuture);
            dealServer.sendMessage(po);
            return getMessageFutureResult(completeFuture,resultPo);
        }
        catch (Exception ex)
        {
            resultPo.getConfig().setDealResult(ExportDealResultTypeEnum.fail.code);
            resultPo.getConfig().setErrorMessage("等待处理异常："+ex.getMessage());
            return resultPo;
        }
    }

    public static String sendDataNoWaitToServer(TransferMessageDto po) {
        ExportDealServer dealServer = getDealServer();

        if (dealServer == null) {
            return "未找到注册中心链接信息";
        }
        dealServer.sendMessage(po);
        return null;
    }

    public static TransferMessageDto sendData(TransferMessageDto po,boolean fixed) {
        TransferMessageDto resultPo = sendDataToServer(po);
        if(resultPo.getConfig().getDealResult() != ExportDealResultTypeEnum.nextIp.code )
        {
            return resultPo;
        }

        int i=0;
        while (resultPo.getConfig().getDealResult() == ExportDealResultTypeEnum.nextIp.code && i< 3)
        {
            i++;
            if(!fixed)
            {
                po.getConfig().setClient(null);
            }
            resultPo = sendDataToServer(po);
        }
        return resultPo;
    }

    private static TransferMessageDto getMessageFutureResult(CompletableFuture<TransferMessageDto> completeFuture,TransferMessageDto resultPo)
    {
        try {
            TransferMessageDto dealResultObj = completeFuture.get(310, TimeUnit.SECONDS);
            if (dealResultObj != null) {
                return dealResultObj;
            }

            resultPo.getConfig().setDealResult(ExportDealResultTypeEnum.fail.code);
            resultPo.getConfig().setErrorMessage("等待处理异常：未获取到数据");
            return resultPo;
        }
        catch (Exception ex)
        {
            resultPo.getConfig().setDealResult(ExportDealResultTypeEnum.fail.code);
            resultPo.getConfig().setErrorMessage("等待处理异常："+ex.getMessage());
            return resultPo;
        }
    }

    public static void saveDataToFuture(TransferMessageDto message)
    {
        try {
            String id = message.getConfig().getId();
            CompletableFuture<TransferMessageDto> future = messageFutureMap.get(id);
            if(future != null)
            {
                messageFutureMap.remove(id);
                future.complete(message);
            }
        }
        catch (Exception ex)
        {
            log.error("",ex);
        }
    }
}
